package com.objk.admin.security.service.impl;

import com.google.common.collect.Lists;
import com.objk.admin.security.entity.SysPermission;
import com.objk.admin.security.entity.SysPermissionMenuBean;
import com.objk.admin.security.entity.SysUserRole;
import com.objk.admin.security.mapper.SysMenuMapper;
import com.objk.admin.security.mapper.SysPermissionMapper;
import com.objk.admin.security.mapper.SysRolePermissionMapper;
import com.objk.admin.security.mapper.SysUserRoleMapper;
import com.objk.admin.security.service.IPermissionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * 用户权限相关接口
 *
 * @author yuan 2019/6/25 15:30
 */
@Service("permissionService")
@Slf4j
public class PermissionServiceImpl implements IPermissionService {

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRolePermissionMapper sysRolePermissionMapper;

    @Autowired
    private SysPermissionMapper sysPermissionMapper;

    @Autowired
    private SysMenuMapper menuMapper;

    @Override
    public List<SysPermission> getUserPermissionList(Integer userId) {
        List<SysPermission> sysPermissionList = Lists.newArrayList();

        if (userId != null) {
            SysUserRole sysUserRole = sysUserRoleMapper.selectByUserId(userId);
            if (sysUserRole != null) {
                // 根据角色Id获取权限信息
                sysPermissionList = sysPermissionMapper.selectRolePermissionByRoleId(sysUserRole.getRoleId());
            }
        }

        return sysPermissionList;
    }

    @Override
    public Collection<? extends GrantedAuthority> getUserAuthorities(Integer userId) {
        Collection<SimpleGrantedAuthority> authorities = Lists.newArrayList();

        List<SysPermission> userPermissionList = this.getUserPermissionList(userId);
        if (CollectionUtils.isNotEmpty(userPermissionList)) {
            // java8写法
            // List<SimpleGrantedAuthority> collect = userPermissionList.stream()
            //.map(item -> new SimpleGrantedAuthority(item.getPermissionCode())).collect(Collectors.toList());

            for (SysPermission item : userPermissionList) {
                if (item != null) {
                    SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(item.getPermissionCode());
                    authorities.add(simpleGrantedAuthority);
                }
            }
        }

        return authorities;
    }

    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        String currentUrl = request.getRequestURL().toString();
        // 获取当前登录用户的权限码
        Collection<? extends GrantedAuthority> currentAuthority = authentication.getAuthorities();
        // 获取当前请求路径的所需要的权限码
        Collection<ConfigAttribute> attributesList = this.getAttributes(request);

        if (CollectionUtils.isNotEmpty(currentAuthority) && CollectionUtils.isNotEmpty(attributesList)) {
            Iterator<ConfigAttribute> iterator = attributesList.iterator();
            while (iterator.hasNext()) {
                ConfigAttribute configAttribute = iterator.next();
                String needPermission = configAttribute.getAttribute();
                for (ConfigAttribute item : attributesList) {
                    String attribute = item.getAttribute();
                    if (attribute.trim().equals(needPermission)) {
                        log.info("请求路径：{}，需要的权限码：{}", currentUrl, needPermission);
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * 获取当前路径所需的权限码
     *
     * @param request
     */
    private Collection<ConfigAttribute> getAttributes(HttpServletRequest request) {
        // 获取所有的权限资源信息
        List<SysPermissionMenuBean> sysPermissionMenuBeans = menuMapper.selectAllPermissionCode();
        Collection<ConfigAttribute> attributes = Lists.newArrayList();

        if (CollectionUtils.isNotEmpty(sysPermissionMenuBeans)) {
            SecurityConfig securityConfig;
            for (SysPermissionMenuBean item : sysPermissionMenuBeans) {
                if (StringUtils.isNotEmpty(item.getMenuUrl())) {
                    // 判断当前的资源路径是否符合ant格式
                    if (new AntPathRequestMatcher(item.getMenuUrl()).matches(request)) {
                        securityConfig = new SecurityConfig(item.getPermissionCode());
                        attributes.add(securityConfig);
                    }
                }
            }
        }

        return attributes;
    }
}
